package vg.modules.opener.system;
import vg.core.AModel;
import vg.core.IProgressTask;
import vg.core.VisualGraph;
import vg.core.exception.CoreException;
import vg.core.exception.EnumCriticalityException;
import vg.core.storableGraph.StorableEdge;
import vg.core.storableGraph.StorableGraph;
import vg.core.storableGraph.StorableSubGraph;
import vg.core.storableGraph.StorableVertex;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
/**
* This class reads a gml file as a Graph
*/
public class GMLDecoder implements IDecoder{
private String fileName = null;
private int counter = 0;
private AModel model;
private String graphName;
//-------------------------------------------------------------------------
private String getVal(String str) {
String s = str;
int a = s.indexOf("\"");
int b = s.indexOf("\"", a+1);
if ( a == -1) {
a = s.indexOf(' ');
b = s.indexOf(' ', a + 1);
}
if ( b == -1) {
return s.substring(a + 1);
}
return s.substring(a + 1, b - 1);
}
//TODO add exception when some exist some word between graph, node, edge and '['
private StorableEdge readEdge(BufferedReader input, String lastRead, final ArrayList<StorableVertex> vertexes) throws IOException {
int i, i0;
final String sourceStr = "source";
final String targetStr = "target";
String source = "";
String target = "";
String str = lastRead.trim();
i = str.indexOf('[');
while (i == -1) {
str = input.readLine().trim();
i = str.indexOf('[');
}
i0 = i;
do {
i = str.indexOf(sourceStr, i0);
if (i != -1) {
str = str.substring(i + sourceStr.length());
source = getVal(str);
i0 = source.length() + 2;
continue;
}
i = str.indexOf(targetStr, i0);
if (i != -1) {
str = str.substring(i + targetStr.length());
target = getVal(str);
i0 = target.length() + 2;
continue;
}
i = str.indexOf(']');
if (i != -1)
break;
str = input.readLine().trim();
i0 = 0;
} while (true);
StorableVertex s = null;
StorableVertex t = null;
for (i = 0; i < vertexes.size(); i++) {
if (vertexes.get(i).getId().compareTo(source) == 0)
s = vertexes.get(i);
if (vertexes.get(i).getId().compareTo(target) == 0)
t = vertexes.get(i);
}
if (s == null || t == null) {
//TODO oups
}
return new StorableEdge(s,t,"e" + (counter++));
}
private StorableVertex readNode(BufferedReader input, String lastRead) throws IOException {
int i, i0;
i = lastRead.indexOf('[');
final String idStr = "id";
final String labelStr = "label";
String label;
String id = "";
String s = lastRead.trim();
//TODO add graphic,edgeAnchor,labelAnchor
while (i == -1) {
s = input.readLine().trim();
i = s.indexOf('[');
}
i0 = i;
do {
i = s.indexOf(idStr, i0);
if (i != -1) {
s = s.substring(i + idStr.length());
id = getVal(s);
i0 = id.length() + 2;
continue;
}
i = s.indexOf(labelStr, i0);
if (i != -1) {
s = s.substring(i + labelStr.length());
label = getVal(s);
i0 = label.length() + 2;
continue;
}
i = s.indexOf(']');
if (i != -1)
break;
s = input.readLine().trim();
i0 = 0;
} while (true);
return new StorableVertex(id);
}
private StorableSubGraph readGraph(BufferedReader input, String lastRead) throws IOException {
String str = lastRead;
ArrayList<StorableVertex> vertexes=new ArrayList<StorableVertex>();
ArrayList<StorableEdge> edges=new ArrayList<StorableEdge>();
int i;
boolean directed = false;
final String nodeID = "node";
final String edgeID = "edge";
final String directedID = "directed";
i = str.indexOf('[');
while (i == -1) {
str = input.readLine();
i = str.indexOf('[');
}
do {
i = str.indexOf(nodeID);
if (i != -1) {
str = str.substring(i + nodeID.length());
vertexes.add(readNode(input, str));
str = input.readLine();
continue;
}
i = str.indexOf(edgeID);
if (i != -1) {
str = str.substring(i + edgeID.length());
edges.add(readEdge(input, str, vertexes));
str = input.readLine();
continue;
}
i = str.indexOf(directedID);
if (i != -1) {
str = str.substring(i + edgeID.length());
if (str.indexOf("1") != -1)
directed = true;
str = input.readLine();
continue;
}
i = str.indexOf(']');
if (i != -1)
break;
str = input.readLine();
} while (true);
lastRead = str;
return new StorableSubGraph(vertexes, edges, directed);
}
//------------------------------------------------------------------------------
private Integer decodeGMLFile() throws CoreException{
String str;
StorableGraph graph = null;
try{
File f = new File(fileName);
final long fileSize = (int) f.length();
final FileInputStream fis = new FileInputStream(f);
BufferedReader input=new BufferedReader(new InputStreamReader(fis));
IProgressTask task = new IProgressTask() {
@Override
public long getValue() {
if (fis.getChannel() != null)
try {
return fis.getChannel().position();
} catch (IOException e) {
}
return getLength();
}
@Override
public long getLength() {
return fileSize;
}
};
VisualGraph.progressManager.addTask(task);
int i;
final String gmlID = "graph";
do {
str = input.readLine();
i = str.indexOf(gmlID);
} while (i == -1);
StorableSubGraph ssg = readGraph(input, str.substring(i + gmlID.length()));
model.addStorableSubGraph(ssg);
ArrayList<Integer> subgraphIds = new ArrayList<Integer>();
subgraphIds.add(ssg.getStorableId());
graph = new StorableGraph(graphName, null, ssg.getStorableId());
model.addStorableGraph(graph, subgraphIds);
VisualGraph.progressManager.removeTask(task);
} catch (IOException e) {
VisualGraph.log.printStackTrace(e.getStackTrace());
throw new CoreException(e.getMessage(), EnumCriticalityException.FAILED);
}
return(graph.getStorableId());
}
public Integer decode(String fileName, AModel model, String graphName) throws CoreException{
this.fileName = fileName;
this.model = model;
this.graphName = graphName;
if (fileName.toLowerCase().endsWith(".gml")){
return decodeGMLFile();
}
else{
return null;
}
}
}